;收录以作学习
;-------------------------------------------------------------------------------- 
;此模板是纯DOS程序代码,需要MASM5.0,编译时请使用"编译 -> DOS"方式。 
;-------------------------------------------------------------------------------- 
Init_game macro op1,op2,op3,op4,op5,op6  

mov cx,00h  
mov dh,op1  
mov dl,op2 
op6:  
mov ah,02h 
mov bh,00h  
int 10h 

push cx 
mov ah,0ah 
mov al,op3 
mov bh,00h 
mov cx,01h 
int 10h 
pop cx 

inc cx 
inc op4 
cmp cx,op5 
jne op6  

endm 

clear_screen macro op1,op2,op3,op4  
mov ah,06h  
mov al,00h 
mov bh,07h 
mov ch,op1 
mov cl,op2 
mov dh,op3 
mov dl,op4 
int 10h 

mov ah,02h 
mov bh,00h 
mov dh,00h 
mov dl,00h 
int 10h 
endm 


menu macro op1,op2,op3  
mov ah,02h 
mov bh,00h 
mov dh,op1 
mov dl,op2 
int 10h 

mov ah,09h 
lea dx,op3 
int 21h 
endm 


data segment  

linjiang db "Made by lin jiang$"  
no db "NO.:021411$" 
meg db "Let us have a game!!Come on!!$" 
meg1 db "**Select Menu**$" 
meg2 db "Please select the game speed,ESC to quit.$" 
meg3 db "1.Very slow Too easy,speed up!$" 
meg4 db "2.Slow Everybody can deal.$" 
meg5 db "3.Nomal I think you can deal!$" 
meg6 db "4.Fast A challenge.Pay attention!$" 
meg7 db "5.Very Fast Too hard,Have a try?$" 
meg8 db "6.Fastest Are you crazy??$" 
meg9 db "*Select the number among 1-6 and press ENTER to start!*$" 
meg10 db "Game Speed Select:$" 

hotkey db "When you are playing games:$"  
hotkey1 db "ESC to return to menu$" 
hotkey2 db "SPACE to pause the game$" 
hotkey3 db "Press any key to play games......$" 
hotkey4 db "Are you ready??$" 

failmeg db "The letter is arrive the bottom, You are lost ! :($"  
failmeg0 db "Press ENTER to go on......$" 
failmeg1 db "Game is over!$" 
failmeg2 db "Press ENTER to return menu and press ESC to exit!$" 
failmeg3 db "Bye-Bye!Thank for your playing!!$" 
failmeg4 db "Press any key to quit......$" 

speed dw 00d,1200d,800d,600d,400d,200d,100d  


letters db "jwmilzoeucgpravskntxhdyqfb"  
db "iytpkwnxlsvxrmofzhgaebudjq" 
db "nwimzoexrphysfqtvdcgljukda" 

letters_bak db "jwmilzoeucgpravskntxhdyqfb"  
db "iytpkwnxlsvxrmofzhgaebudjq"  
db "nwimzoexrphysfqtvdcgljukda" 

letter_counter db 0  
life_flag db 78 dup(0) 

position_flag db 78 dup(0)  
present_position db 1  

  

data ends 

stack segment para stack 'stack' 
db 64 dup(0) 
stack ends 

  

code segment 
main proc far 
assume cs:code,ds:data,ss:stack 
start: 

mov ax,data 
mov ds,ax 

mov letter_counter,00h  
mov present_position,1  

lea si,position_flag  

mov ah,00h 
mov cx,00h 

init_postion_flag:  
mov [si],ah 
inc si 
inc cx 
cmp cx,78d 
jne init_postion_flag 

lea di,letters  
lea si,letters_bak 
mov cx,00h 
init_letters: 
mov ah,[si] 
mov [di],ah 
inc si 
inc di 
inc cx 
cmp cx,78d 
jne init_letters 


mov ah,00h 
lea si,life_flag 
mov cx,00h 
init_life_flag: 
mov [si],ah 
inc si 
inc cx 
cmp cx,78d 
jne init_life_flag 

  


mov cx,00h  
mov ah,01h  
or ch,00010000b 
int 10h 

clear_screen 00d,00d,24d,79d  

  

Init_game 00d,00d,0ah,dl,80d,nextsign1  

Init_game 24d,00d,0ah,dl,80d,nextsign2 

Init_game 00d,00d,0ah,dh,25d,nextsign3 

Init_game 00d,79d,0ah,dh,25d,nextsign4 

  


menu 01d,15d,meg ;菜单信息的宏展开 
menu 01h,61d,linjiang  
menu 03d,20d,meg1 
menu 03d,68d,no 
menu 05d,15d,meg2 
menu 07d,15d,meg3 
menu 09d,15d,meg4 
menu 11d,15d,meg5 
menu 13d,15d,meg6 
menu 15d,15d,meg7 
menu 17d,15d,meg8 
menu 19d,15d,meg9 
menu 22d,15d,meg10 

  

  

input: mov ah,02h  
mov bh,00h 
mov dh,22d 
mov dl,33d 
int 10h 

mov ah,0ah 
mov al," " 
mov bh,00h 
mov cx,01h 
int 10h 

mov ah,01h 
int 21h 
retry: cmp al,"1" 
je speed1 
cmp al,"2" 
je speed2 
cmp al,"3" 
je speed3 
cmp al,"4" 
je speed4 
cmp al,"5" 
je speed5 
cmp al,"6" 
je speed6 
cmp al,1bh 
je to_over0 
jmp input 

to_over0:jmp over  


speed1: mov ah,01h  
int 21h 
cmp al,0dh 
jne otherkey 
mov ax,speed+2 
mov speed,ax 
jmp begin  

speed2: mov ah,01h  
int 21h 
cmp al,0dh 
jne otherkey 
mov ax,speed+4 
mov speed,ax 
jmp begin 

speed3: mov ah,01h  
int 21h 
cmp al,0dh 
jne otherkey 
mov ax,speed+6 
mov speed,ax 
jmp begin 

speed4: mov ah,01h  
int 21h 
cmp al,0dh 
jne otherkey 
mov ax,speed+8 
mov speed,ax 
jmp begin 

speed5: mov ah,01h  
int 21h 
cmp al,0dh 
jne otherkey 
mov ax,speed+10 
mov speed,ax 
jmp begin 

speed6: mov ah,01h  
int 21h 
cmp al,0dh 
jne otherkey 
mov ax,speed+12 
mov speed,ax 
jmp begin  

otherkey: ; 处理重复输入的代码段 

push ax 
mov ah,02h 
mov bh,00h 
mov dh,22d 
mov dl,34d 
int 10h 

mov ah,0ah 
mov al," " 
mov bh,00h 
mov cx,01h 
int 10h 

mov ah,02h 
mov bh,00h 
mov dh,22d 
mov dl,33d 
int 10h 
pop ax 

mov dx,ax 
mov ah,02h 
int 21h 

jmp retry  

begin:  

clear_screen 01d,01d,23d,78d  

menu 08d,20d,hotkey  
menu 10d,20d,hotkey1 
menu 12d,20d,hotkey2 
menu 14d,20d,hotkey4 
menu 16d,20d,hotkey3 

mov ah,07h 
int 21h 

clear_screen 01d,01d,23d,78d  
Init_game 23d,01d,01h,dl,78d,nextsign5 

mov ah,02h ;光标初始化 
mov bh,00h 
mov dh,01h 
mov dl,01h 
int 10h 

mov cx,00h  
lea si,letters 
nextletter: ; 初始化屏幕上方的字母 
mov ah,02h 
mov dl,[si] 
int 21h 

inc si 
inc cx 
cmp cx,78d 
je nextcycle 
jmp nextletter 


from_front: ; 相关循环的算法 
sub present_position,78d  
jmp gobackto_si 

find_zero:cmp letter_counter,78d  
je recycle 

cmp present_position,78d 
je from_one 

mov ah,00h 
nextsi: add present_position,01h 
inc si 
cmp [si],ah 
je gobackto_di 

cmp present_position,78d 
je from_one 

jmp nextsi 

  

from_one:mov present_position,01h  

jmp gobackto_si 

recycle:mov letter_counter,00h 
mov present_position,01d 
lea si,position_flag 
mov cx,00h 

mov ah,00h 
clearsi: mov [si],ah 
inc cx 
cmp cx,78d 
je nextcycle 
inc si 
jmp clearsi 

  

nextcycle:  
lea di,letters 
lea si,position_flag 
add present_position,31d 
cmp present_position,78 
ja from_front 


gobackto_si: 
add si,word ptr present_position 
dec si 
mov ah,[si] 
cmp ah,01h 
je find_zero 


gobackto_di: 
mov ah,01h 
mov [si],ah 
add di,word ptr present_position 
dec di 
mov dl,present_position 

  

mov ah,02h ; 字母下落的代码段部分 
mov bh,00h  
mov dh,01h 
int 10h 

mov cx,00h 
nextrow:push cx ; 新的一行 


mov cx,00h 
out_cycle: ; 延迟 
push cx 
mov cx,00h 
in_cycle: 
add cx,01h 
cmp cx,50000d 
jne in_cycle  

push dx 
mov ah,06h 
mov dl,0ffh 
int 21h 
pop dx 

jz pass ; 如果键盘缓冲区部分为空,则跳转 


cmp al,1bh ; 如果键入ESC，则返回主菜单 
je to_start1 

cmp al," " ;如果键入SPACE，则游戏暂停 
je pause 

cmp al,[di] ;输入字母正确！跳转! 
je disappear 

  

pass: 
pop cx 
inc cx 
cmp cx,speed 
je print 
jmp out_cycle 


pause: push dx ;暂停处理 
mov ah,06h 
mov dl,0ffh 
int 21h 
pop dx 
cmp al," " 
jne pause 

jmp pass 


to_start1: ;返回主菜单 
jmp start  

print:  


mov ah,0ah  
mov al," " 
mov bh,00h 
mov cx,01h 
int 10h 

inc dh 
mov ah,02h 
mov bh,00h 
int 10h 

mov ah,0ah 
mov al,[di] 
mov bh,00h 
mov cx,01h 
int 10h 

pop cx 
inc cx 
cmp cx,21d 
je print_next_letter 
jmp nextrow ; 下一行 

disappear: ; 击中字母后的相关处理 
pop cx 
pop cx 

mov ah,0ah 
mov al," " 
mov bh,00h 
mov cx,01h 
int 10h 


jmp hit  


print_next_letter: ; 处理原位置的空缺 
lea si,life_flag 
add si,word ptr present_position 
dec si 

mov ah,[si] 
cmp ah,1 
je fail 

mov ah,0ah 
mov al," " 
mov bh,00h 
mov cx,01h 
int 10h 


inc dh  
mov ah,02h 
mov bh,00h 
int 10h 

mov ah,0ah 
mov al," " 
mov bh,00h 
mov cx,01h 
int 10h 


mov ah,1 
mov [si],ah 


hit: mov ah,02h 
mov bh,00h 
mov dh,01h 
mov dl,present_position 
int 10h 

mov al,[di] ; 出现下一个新字母的数法 
add al,7 
cmp al,7ah 
ja convey_letter 
mov ah,0ah 
mov bh,00h 
mov cx,01h 
int 10h 

mov [di],al 
add letter_counter,01h 
jmp nextcycle 

convey_letter:  
sub al,7ah 
add al,61h 
mov ah,0ah 
mov bh,00h 
mov cx,01h 
int 10h 

mov [di],al 
add letter_counter,01h 
jmp nextcycle  

fail: mov ah,0ah ;游戏失败后的相关处理 
mov al," " 
mov cx,01h 
int 10h 

inc dh 
mov ah,02h 
mov bh,00h 
int 10h 

mov ah,0ah 
mov al,[di] 
mov bh,00h 
mov cx,01h 
int 10h 

mov ah,02h 
mov bh,00h 
mov dh,12d 
mov dl,17d 
int 10h 

push dx 
mov ah,09h 
lea dx,failmeg 
int 21h 
pop dx 

add dh,2 
mov ah,02h 
mov bh,00h  
int 10h 

mov ah,09h 
lea dx,failmeg0 
int 21h 

re: mov ah,07h 
int 21h 
cmp al,0dh 
jne re 


clear_screen 01,01,23,78 
mov ah,02h 
mov bh,00h 
mov dh,11d 
mov dl,20d 
int 10h 

push dx 
mov ah,09h 
lea dx,failmeg1 
int 21h 
pop dx 

inc dh 
inc dh 
mov ah,02h 
mov bh,00h 
int 10h 

mov ah,09h 
lea dx,failmeg2 
int 21h 

notkey:  
mov ah,07h 
int 21h 
cmp al,0dh 
je to_start 
cmp al,1bh 
je over 
jmp notkey 
to_start:  
clear_screen 00,00,24,79 
jmp start 

over: clear_screen 01,01,23,78  
mov ah,02h 
mov bh,00h 
mov dh,11d 
mov dl,15h 
int 10h 

mov ah,09h 
lea dx,failmeg3 
int 21h 

mov ah,02h 
mov bh,00h 
mov dh,13d 
mov dl,15h 
int 10h 

mov ah,09h 
lea dx,failmeg4 
int 21h 

mov ah,07h 
int 21h 

mov ah,07h 
int 21h 

clear_screen 00,00,24,79  

mov ax,4c00h 
int 21h 


main endp 
code ends 
end start 
